package br3akr.DeadlyDinnerParty.Server.Actions;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import br3akr.DeadlyDinnerParty.Server.Engine.Session;
import br3akr.DeadlyDinnerParty.Server.Engine.TimedActionTask;
import br3akr.DeadlyDinnerParty.Server.Exceptions.DeadlyDinnerPartyException;
import br3akr.DeadlyDinnerParty.Server.World.Area;
import br3akr.DeadlyDinnerParty.Server.World.Body;
import br3akr.DeadlyDinnerParty.Server.World.Exit;
import br3akr.DeadlyDinnerParty.Server.World.GameCharacter;

public class SearchAction extends Action implements TimerAction {
	boolean actionComplete;
    private ActionResponse actionResponse;
	private static final int START  = 1;
	private static final int CONTINUING = 2;
	private static final int COMPLETE = 3;
    public static final Set<String> keywords;
    private int curStep = START;
    private Area searchingLocation = null;
    private String currentDescription;
    TimerTask task = null;
    
	static
	{
		Set<String>tempKeywords = new HashSet<String>();
		tempKeywords.add("Search");
		keywords = Collections.unmodifiableSet(tempKeywords);
	}
    
    public SearchAction() {
        super("Search", false);
    }
    
    public ActionResponse doAction(String action, Session session) throws DeadlyDinnerPartyException {
    	if (curStep == START) {
			if (action == null) {
				actionComplete = true;
				throw new DeadlyDinnerPartyException ("No action found.");
			}
			if (session == null) {
				actionComplete = true;
				throw new DeadlyDinnerPartyException ("No session found.");
			}
			
			GameCharacter actor = session.getCharacter();
			
			if (actor == null) {
				actionComplete = true;
				throw new DeadlyDinnerPartyException ("No character found for your session.");
			}
	    	
	    	actionResponse = new ActionResponse();
	    	actionResponse.setActingCharacter(session.getCharacter());
	    	Area location = session.getCharacter().getLocation();
	    	Set<GameCharacter> localOnlookers = location.getAreaOnlookers(session.getCharacter(), null);	    	
	    	searchingLocation = location;
	    	actionResponse.addAffectedArea(location);
			actionResponse.addOnlookers(localOnlookers, session.getCharacter().getName() + " begins searching the room.");
			actionResponse.setActingCharacterDescription("You begin searching the room.");
			task = new TimedActionTask(session, this);
			Timer timer = new Timer();
			timer.schedule(task, 5000);
			currentDescription = actor.getName() + " is searching the room for something.";
	    	curStep = CONTINUING;
    	} else if (curStep == CONTINUING) {
    		if (action.equalsIgnoreCase("QUIT") || action.equalsIgnoreCase("Q") || action.equalsIgnoreCase("STOP") || action.equalsIgnoreCase("DONE")) {
    			actionComplete = true;
        		actionResponse = new ActionResponse();
        		actionResponse.addAffectedArea(searchingLocation);
        		Set<GameCharacter> localOnlookers = searchingLocation.getAreaOnlookers(session.getCharacter(), null);
        		actionResponse.addOnlookers(localOnlookers, session.getCharacter().getName() + " stops searching the room.");
        		actionResponse.setActingCharacter(session.getCharacter());
        		actionResponse.setActingCharacterDescription("You stop searching the area.");
    			task.cancel();
    		}
    	} else if (curStep == COMPLETE) {
    		actionComplete = true;
    		actionResponse = new ActionResponse();
    		actionResponse.addAffectedArea(searchingLocation);
    		Set<GameCharacter> localOnlookers = searchingLocation.getAreaOnlookers(session.getCharacter(), null);
    		actionResponse.addOnlookers(localOnlookers, session.getCharacter().getName() + " stops searching the room.");
    		actionResponse.setActingCharacter(session.getCharacter());
    		StringBuilder sb = new StringBuilder();
    		Exit secretExit = searchingLocation.getExit(Exit.ExitDirections.SECRET); 
    		if (secretExit != null && !secretExit.knowsSecretExit(session.getCharacter())) {
    			sb.append("\nA secret exit out of the area.");
    			secretExit.addKnowsSecretExit(session.getCharacter());
    		}
    		for (Body body : searchingLocation.getBodies()) {
    			if (body.isHiddenFrom(session.getCharacter())) {
    				sb.append("\n" + body.getDescription(0));
    			}
    			body.removeHiddenFrom(session.getCharacter());
    		}
    		if (sb.length() == 0) {
    			sb.append("You finish searching the area and have found nothing.");
    		} else {
    			sb.insert(0, "You finish searching the area and have found:");
    		}
    		actionResponse.setActingCharacterDescription(sb.toString());
    	}
        return actionResponse;
    }
    
	public void reset() {
		actionResponse = null;
		actionComplete = false;
	}
	
    public ActionResponse getActionResponse() {
		return actionResponse;
	}

	public boolean isComplete() {
		return actionComplete;
	}
    
    public Set<String> getKeywords() {
        return keywords;
    }
    
	@Override
	public void nextStep() {
		if (curStep == CONTINUING) {
			curStep = COMPLETE;
		}
		
		if (curStep == COMPLETE) {
			actionComplete = true;
		}
	}

	@Override
	public String getCurrentDescription() {
		return currentDescription;
	}

	@Override
	public long timeLeft() {
		return 0;
	}
}